﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Collections.ObjectModel;

namespace Vit.Report.XmlWebReport
{
    public class TableRowElement : CellElement
    {
        private TableElement table;
        private List<TableCellElement> cells;

        public TableRowElement(TableElement table, string topLeftPosition, string bottomRightPosition, string content)
            : base(table.Page, topLeftPosition, bottomRightPosition, content)
        {
            this.table = table;
            this.table.Rows.Add(this);
            RowIndex = this.table.Rows.Count;
            Index = RowIndex;
        }

        public TableRowElement(TableElement table, RectanglePosition rect, string content)
            : base(table.Page, rect, content)
        {
            this.table = table;
            this.table.Rows.Add(this);
            RowIndex = this.table.Rows.Count;
            Index = RowIndex;
        }

        protected override void Initialize()
        {
            base.Initialize();
            PositionType = PositionType.Fix;
            cells = new List<TableCellElement>();
            this.CssClass += " table-row";
        }

        public override void CalculatePosition()
        {
            if (IsPrintable == false)
                return;

            //base.CalculatePosition();

            RectanglePosition last = null;
            int maxYOffset = 0;
            foreach (TableCellElement cell in Cells)
            {
                cell.CalculatePosition();
                if (last == null || (last.BottomIndex < cell.RectanglePosition.BottomIndex))
                {
                    last = cell.RectanglePosition.Clone();
                }
                if (maxYOffset < cell.YOffset)
                    maxYOffset = cell.YOffset;
            }

            if (last.BottomIndex > this.RectanglePosition.BottomIndex)
            {
                this.RectanglePosition.AppendTo(0, last.BottomIndex - this.RectanglePosition.BottomIndex);
                this.Cells.ForEach(o => o.RectanglePosition.AppendTo(0, last.BottomIndex - o.RectanglePosition.BottomIndex));
            }

            page.YOffset += maxYOffset;

            if (extraYRow != null && extraYRow.Cells.Count < this.Cells.Count)
            {
                foreach (TableCellElement cell in this.Cells)
                {
                    if (extraYRow.Cells.Any(o => o.CellIndex == cell.CellIndex))
                        continue;

                    RectanglePosition extraRect = new RectanglePosition(
                        string.Format("{0}{1}", cell.RectanglePosition.LeftIndex, extraYRow.RectanglePosition.TopIndex),
                        string.Format("{0}{1}", cell.RectanglePosition.RightIndex, extraYRow.RectanglePosition.BottomIndex));
                    TableCellElement extraCell = new TableCellElement(extraYRow, extraRect, "");
                    extraCell.ID = cell.ID + "_extraYCell";
                    extraCell.CellIndex = cell.CellIndex;
                }

                //List<TableCellElement> tempCells = new List<TableCellElement>();
                //tempCells.AddRange(extraYRow.Cells);
                //extraYRow.Cells.Clear();
                //string extraCellCssClass = "";
                //if (extraYRow.RectanglePosition.TopIndex == 1)
                //    extraCellCssClass = " border-t";
                //for (int i = 0; i < this.Cells.Count; i++)
                //{
                //    string cellTopLeft = string.Format("{0}{1}", this.Cells[i].RectanglePosition.LeftIndex, extraYRow.RectanglePosition.TopIndex);
                //    string cellBottomRight = string.Format("{0}{1}", this.Cells[i].RectanglePosition.RightIndex, extraYRow.RectanglePosition.TopIndex + extraYRow.Table.RowSpan - 1);
                //    TableCellElement extraCell = new TableCellElement(extraYRow, cellTopLeft, cellBottomRight, "");
                //    extraCell.CssClass += extraCellCssClass;
                //    extraCell.ID = this.Cells[i].ID + "_extraYCell";
                //}

                //foreach (TableCellElement tcell in tempCells)
                //{
                //    TableCellElement cell = extraYRow.Cells[tcell.CellIndex - 1];
                //    cell.RectanglePosition = tcell.RectanglePosition;
                //    cell.Content = tcell.Content;
                //}
            }
        }

        public override void Render(TextWriter writer)
        {
            if (IsPrintable == false)
                return;

            foreach (CellElement cell in Cells)
                cell.Render(writer);
        }

        public override void Move(int xOffset, int yOffset)
        {
            base.Move(xOffset, yOffset);

            foreach (TableCellElement cell in Cells)
                cell.Move(xOffset, yOffset);
        }

        public override void Offset(float x, float y)
        {
            base.Offset(x, y);

            foreach (TableCellElement cell in Cells)
                cell.Offset(x, y);
        }

        protected override void AddToPage()
        {
        }

        public void EnsureExtraYRow()
        {
            if (extraYRow == null)
            {
                table.EnsureExtraYTable();
                int top = table.ExtraYTable.Rows.Count > 0 ? table.ExtraYTable.Rows.Count * table.ExtraYTable.RowSpan : 1;
                string rowTopLeft = string.Format("{0}{1}", table.ExtraYTable.RectanglePosition.LeftIndex, top);
                string rowBottomRight = string.Format("{0}{1}", this.RectanglePosition.RightIndex, top + table.ExtraYTable.RowSpan - 1);
                extraYRow = new TableRowElement(table.ExtraYTable, rowTopLeft, rowBottomRight, "");

                extraYRow.ID = this.ID + "_extraYRow";
            }
        }

        protected TableRowElement extraYRow;
        public TableRowElement ExtraYRow { get { return extraYRow; } }
     
        public List<TableCellElement> Cells { get { return cells; } }
        public int RowIndex { get; set; }
        public TableElement Table { get { return table; } }
    }
}
